﻿/* ***********************************************
 * Author		:  kingthy
 * Email		:  kingthy@gmail.com
 * Description	:  DbDataPagingReader
 *
 * ***********************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;
using System.Data;
using KT.Core.Extensions;
namespace KT.Framework.Database
{
    /// <summary>
    /// 数据分页读取
    /// </summary>
    public class DbDataPagingReader
    {
        /// <summary>
        /// 根据DbConnection对象实例化
        /// </summary>
        /// <param name="connection"></param>
        public DbDataPagingReader(DbConnection connection)
            : this(new DbHelper(connection))
        {}
        /// <summary>
        /// 根据数据库帮助对象实例化
        /// </summary>
        /// <param name="dbHelper"></param>
        public DbDataPagingReader(DbHelper dbHelper)
        {
            this.DbHelper = dbHelper;
            this.PageNumber = 1;
            this.PageSize = 10;
            this.RecordCount = 0;
            this.KeepConnection = false;
        }
        /// <summary>
        /// 数据库连接当前是否是处于已打开状态
        /// </summary>
        private bool KeepConnection;

        /// <summary>
        /// 返回当前的数据源连接对象
        /// </summary>
        public DbHelper DbHelper { get; private set; }

        /// <summary>
        /// 返回或设置数据获取语句。即是Select语句部分（不带WHERE与ORDER BY部分），如："SELECT * FROM Table1"
        /// </summary>
        public string Select { get; set; }

        /// <summary>
        /// 
        /// </summary>
        private DbConditionBuilder _Condition;
        /// <summary>
        /// 返回条件构造器，用于构造查询条件,即是WHERE部分语句
        /// </summary>
        public DbConditionBuilder Condition
        {
            get
            {
                if (_Condition == null)
                {
                    _Condition = new DbConditionBuilder();
                }
                return _Condition;
            }
            set
            {
                if(_Condition != null)_Condition.Clear();
                _Condition = value;
            }
        }

        /// <summary>
        /// 返回或设置排列字段,如:Id ASC，不带"Order By"关键字
        /// </summary>
        public string OrderBy { get; set; }

        /// <summary>
        /// 返回或设置当前页码
        /// </summary>
        public int PageNumber { get; set; }

        /// <summary>
        /// 返回或设置页码大小，默认值是10条每页
        /// </summary>
        public int PageSize { get; set; }

        /// <summary>
        /// 返回页码总数
        /// </summary>
        public int PageCount
        {
            get
            {
                if (this.RecordCount < 1) return 1;

                return (int)Math.Ceiling((double)this.RecordCount / this.PageSize);
            }
        }

        private int _RecordCount;
        /// <summary>
        /// 返回记录总数
        /// </summary>
        public int RecordCount
        {
            get
            {
                return _RecordCount;
            }
            protected set
            {
                _RecordCount = value;
                //修正页码数
                this.PageNumber = Math.Min(this.PageNumber, this.PageCount);
            }
        }

        #region 打开数据源
        /// <summary>
        /// 开始执行
        /// </summary>
        protected virtual void BeginExecute()
        {
            if (string.IsNullOrEmpty(this.Select)) throw new ArgumentNullException("Select", "无法获取空的数据，请先设置Select属性");
            this.KeepConnection = this.DbHelper.KeepConnection;
            this.DbHelper.KeepConnection = true;
        }
        /// <summary>
        /// 执行已结束
        /// </summary>
        protected virtual void EndExecute()
        {
            //如果原非处于已打开状态且当前是已打开状态则关闭连接。
            if (this.KeepConnection != this.DbHelper.KeepConnection)
            {
                this.DbHelper.KeepConnection = this.KeepConnection;
                if(!this.KeepConnection) this.DbHelper.Close();
            }
        }
        #endregion

        #region 获取页码的总数
        /// <summary>
        /// 初始化页码的总数
        /// </summary>
        protected virtual void InitPageCount()
        {
            StringBuilder sql = new StringBuilder(this.Select.Length + 40);
            sql.AppendFormat("SELECT COUNT(*) FROM ({0} {1}) as {2}", this.Select, this.Condition.ToString(), this.DbHelper.QuoteIdentifier("_tb1"));

            using (var command = this.DbHelper.CreateDbCommandWrapped(sql.ToString(), this.Condition.Parameters))
            {
                this.RecordCount = command.ExecuteScalar().As<int>();
            }
        }
        #endregion

        #region 获取数据
        /// <summary>
        /// 获取当前页的数据并返回一个数据对象列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public virtual List<T> ReadAsDbObjectList<T>()
            where T : DbObject, new()
        {
            try
            {
                this.BeginExecute();
                this.InitPageCount();
                int startIndex = (this.PageNumber - 1) * this.PageSize;
                if (this.RecordCount > 0)
                {
                    StringBuilder sql = new StringBuilder(this.Select.Length + 40);
                    sql.Append(this.Select);
                    if (this.Condition.HasCondition)
                    {
                        sql.Append(" ");
                        sql.Append(this.Condition.ToString());
                    }
                    if (!string.IsNullOrEmpty(this.OrderBy))
                    {
                        sql.Append(" ORDER BY ");
                        sql.Append(this.OrderBy);
                    }
                    using (var command = this.DbHelper.CreateDbCommandWrapped(sql.ToString(), this.Condition.Parameters))
                    {
                        return command.ExecuteDbObjectList<T>(startIndex, this.PageSize);
                    }
                }
                else
                {
                    return new List<T>();
                }
            }
            finally
            {
                this.EndExecute();
            }
        }

        /// <summary>
        /// 获取当前页的数据并返回一个数据表
        /// </summary>
        /// <returns></returns>
        public virtual DataTable ReadAsDataTable()
        {
            return this.ReadAsDbObjectList<DbObject>().ToDataTable();
        }
        #endregion
    }
}
